﻿using System.Windows;
using System.Windows.Controls.Primitives;

namespace Notoric.View.Music.CWNotation.Controls
{
    /// <summary>
    /// Implements a drag thumb for positioning elements that implement <see cref="ViewModel.IPositionable"/> interface.
    /// </summary>
    public class PositionableDragThumb : Thumb
    {
        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="PositionableDragThumb"/> class.
        /// </summary>
        public PositionableDragThumb()
        {
            DragCompleted += new DragCompletedEventHandler(PositionableDragThumb_DragCompleted);
            DragDelta += new DragDeltaEventHandler(PositionableDragThumb_DragDelta);
            DragStarted += new DragStartedEventHandler(PositionableDragThumb_DragStarted);
        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// Handles the DragStarted event of the thumb control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="DragStartedEventArgs"/> instance containing the event data.</param>
        private void PositionableDragThumb_DragStarted(object sender, DragStartedEventArgs e)
        {
            draggedElement = DataContext as ViewModel.IPositionable;
        }

        /// <summary>
        /// Handles the DragDelta event of the thumb control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="DragDeltaEventArgs"/> instance containing the event data.</param>
        private void PositionableDragThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            if (draggedElement != null)
            {
                draggedElement.Left += e.HorizontalChange;
                draggedElement.Top += e.VerticalChange;
            }
        }

        /// <summary>
        /// Handles the DragCompleted event of the thumb control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="DragCompletedEventArgs"/> instance containing the event data.</param>
        private void PositionableDragThumb_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            if (draggedElement != null)
            {
                if (draggedElement is ViewModel.ViewModelElement)
                    ((ViewModel.ViewModelElement)draggedElement).CommitChanges();
                draggedElement = null;
            }
        }

        #endregion

        #region Dependency Properties Fields

        /// <summary>
        /// Indentifies the <see cref="Content"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
            "Content", typeof(object), typeof(PositionableDragThumb)
            );

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets or sets the content of this control.<br/>
        /// This is a dependency property.
        /// </summary>
        /// <value>
        /// <para>
        /// Type: <see cref="object"/>
        /// </para>
        /// <para>
        /// The content of this control.
        /// </para>
        /// </value>
        public object Content
        {
            get { return GetValue(ContentProperty); }
            set { SetValue(ContentProperty, value); }
        }

        #endregion

        #region Private Fields

        /// <summary>
        /// Holds a reference to the element that is being dragged.
        /// </summary>
        private ViewModel.IPositionable draggedElement;

        #endregion
    }
}
